const { validationResult } = require('express-validator');
const User = require('../models/User');
const { generateTokens, verifyRefreshToken } = require('../utils/jwt');

/**
 * 认证控制器
 */
class AuthController {

  /**
   * 用户注册
   */
  static async register(req, res) {
    try {
      // 检查验证错误
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入数据验证失败',
          errors: errors.array()
        });
      }

      const { username, email, password, name } = req.body;

      // 检查用户是否已存在
      const existingUser = await User.findByEmailOrUsername(email);
      if (existingUser) {
        return res.status(409).json({
          success: false,
          message: '用户已存在',
          field: existingUser.email === email ? 'email' : 'username'
        });
      }

      // 检查用户名是否已被使用
      const existingUsername = await User.findOne({ username });
      if (existingUsername) {
        return res.status(409).json({
          success: false,
          message: '用户名已被使用',
          field: 'username'
        });
      }

      // 创建新用户
      const newUser = new User({
        username,
        email,
        password,
        name
      });

      await newUser.save();

      // 生成JWT令牌
      const tokens = generateTokens(newUser);

      // 保存刷新令牌到数据库
      newUser.refreshToken = tokens.refreshToken;
      await newUser.save();

      res.status(201).json({
        success: true,
        message: '注册成功',
        data: {
          user: {
            id: newUser._id,
            username: newUser.username,
            email: newUser.email,
            name: newUser.name,
            avatar: newUser.avatar,
            bio: newUser.bio,
            followersCount: newUser.followersCount,
            followingCount: newUser.followingCount,
            isVerified: newUser.isVerified,
            createdAt: newUser.createdAt
          },
          tokens
        }
      });

    } catch (error) {
      console.error('注册错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误',
        error: process.env.NODE_ENV === 'development' ? error.message : undefined
      });
    }
  }

  /**
   * 用户登录
   */
  static async login(req, res) {
    try {
      // 检查验证错误
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入数据验证失败',
          errors: errors.array()
        });
      }

      const { identifier, password } = req.body;

      // 查找用户
      const user = await User.findByEmailOrUsername(identifier);
      if (!user) {
        return res.status(401).json({
          success: false,
          message: '邮箱/用户名或密码错误'
        });
      }

      // 检查用户是否激活
      if (!user.isActive) {
        return res.status(403).json({
          success: false,
          message: '账户已被禁用，请联系管理员'
        });
      }

      // 验证密码
      const isValidPassword = await user.comparePassword(password);
      if (!isValidPassword) {
        return res.status(401).json({
          success: false,
          message: '邮箱/用户名或密码错误'
        });
      }

      // 生成JWT令牌
      const tokens = generateTokens(user);

      // 更新用户信息
      user.refreshToken = tokens.refreshToken;
      user.lastLoginAt = new Date();
      await user.save();

      res.json({
        success: true,
        message: '登录成功',
        data: {
          user: {
            id: user._id,
            username: user.username,
            email: user.email,
            name: user.name,
            avatar: user.avatar,
            bio: user.bio,
            location: user.location,
            followersCount: user.followersCount,
            followingCount: user.followingCount,
            isVerified: user.isVerified,
            lastLoginAt: user.lastLoginAt,
            createdAt: user.createdAt
          },
          tokens
        }
      });

    } catch (error) {
      console.error('登录错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误',
        error: process.env.NODE_ENV === 'development' ? error.message : undefined
      });
    }
  }

  /**
   * 刷新访问令牌
   */
  static async refreshToken(req, res) {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入数据验证失败',
          errors: errors.array()
        });
      }

      const { refreshToken } = req.body;

      // 验证刷新令牌
      const decoded = verifyRefreshToken(refreshToken);

      // 查找用户并验证刷新令牌
      const user = await User.findById(decoded.userId);
      if (!user || user.refreshToken !== refreshToken) {
        return res.status(401).json({
          success: false,
          message: '无效的刷新令牌'
        });
      }

      // 检查用户是否激活
      if (!user.isActive) {
        return res.status(403).json({
          success: false,
          message: '账户已被禁用'
        });
      }

      // 生成新的令牌对
      const newTokens = generateTokens(user);

      // 更新数据库中的刷新令牌
      user.refreshToken = newTokens.refreshToken;
      await user.save();

      res.json({
        success: true,
        message: '令牌刷新成功',
        data: {
          tokens: newTokens
        }
      });

    } catch (error) {
      console.error('令牌刷新错误:', error);
      res.status(401).json({
        success: false,
        message: error.message || '令牌刷新失败'
      });
    }
  }

  /**
   * 用户登出
   */
  static async logout(req, res) {
    try {
      // 清除用户的刷新令牌
      const user = await User.findById(req.user.userId);
      if (user) {
        user.refreshToken = null;
        await user.save();
      }

      res.json({
        success: true,
        message: '登出成功'
      });

    } catch (error) {
      console.error('登出错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误'
      });
    }
  }

  /**
   * 获取当前用户信息
   */
  static async getCurrentUser(req, res) {
    try {
      const user = await User.findById(req.user.userId)
        .populate('followers', 'username name avatar')
        .populate('following', 'username name avatar');

      if (!user) {
        return res.status(404).json({
          success: false,
          message: '用户不存在'
        });
      }

      res.json({
        success: true,
        data: {
          user: {
            id: user._id,
            username: user.username,
            email: user.email,
            name: user.name,
            avatar: user.avatar,
            bio: user.bio,
            location: user.location,
            followersCount: user.followersCount,
            followingCount: user.followingCount,
            followers: user.followers,
            following: user.following,
            isVerified: user.isVerified,
            lastLoginAt: user.lastLoginAt,
            createdAt: user.createdAt,
            updatedAt: user.updatedAt
          }
        }
      });

    } catch (error) {
      console.error('获取用户信息错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误'
      });
    }
  }

  /**
   * 修改密码
   */
  static async changePassword(req, res) {
    try {
      const errors = validationResult(req);
      if (!errors.isEmpty()) {
        return res.status(400).json({
          success: false,
          message: '输入数据验证失败',
          errors: errors.array()
        });
      }

      const { currentPassword, newPassword } = req.body;
      const user = await User.findById(req.user.userId);

      if (!user) {
        return res.status(404).json({
          success: false,
          message: '用户不存在'
        });
      }

      // 验证当前密码
      const isValidPassword = await user.comparePassword(currentPassword);
      if (!isValidPassword) {
        return res.status(401).json({
          success: false,
          message: '当前密码错误'
        });
      }

      // 更新密码
      user.password = newPassword;
      user.refreshToken = null; // 清除刷新令牌，强制重新登录
      await user.save();

      res.json({
        success: true,
        message: '密码修改成功，请重新登录'
      });

    } catch (error) {
      console.error('修改密码错误:', error);
      res.status(500).json({
        success: false,
        message: '服务器内部错误'
      });
    }
  }
}

module.exports = AuthController; 